﻿using Microsoft.Playwright;
using System;
using System.Threading.Tasks;

namespace OnlineStore.Common
{
    public class PageNavigation : NavigationUtils
    {
        public PageNavigation(IPage page)
        {
            this.page = page;
        }

        private IPage page;

        private Action<string> printAction;

        public Action<string> PrintAction { get => printAction; set => printAction = value; }

        /// <summary>
        /// 输出日志内容
        /// </summary>
        async Task Print(string text)
        {
            await Task.Run(() =>
            {
                PrintAction(text);
            });
        }

        /// <summary>
        /// 通过 ILocator 对象进行匹配，并执行指定操作，Fill除外
        /// ** request: Locator（默认）,GetByText,GetByLabel,GetByTestId,GetByTitle,GetByAltText,GetByPlaceholder
        /// ** execute: ClickAsync（默认）,CheckAsync,ClearAsync,DblClickAsync
        /// </summary>
        /// <param name="request">请求类型，首字母是大写</param>
        /// <param name="execute">操作类型，首字母大写</param>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public override async Task<bool> NavigationGo(string request, string execute, string elementPath)
        {
            try
            {
                ILocator element = Request(page, request, elementPath);
                if (await element.CountAsync() > 0)
                {
                    await Execute(element, execute);
                    return true;
                }
                else
                {
                    await Print($"找不到元素 {elementPath}");
                    return false;
                }
            }
            catch (Exception)
            {
                throw;
            }
            
        }

        /// <summary>
        /// 通过 QuerySelectorAsync 方式进行匹配，并执行指定操作，Fill除外
        /// ** execute: ClickAsync（默认）,CheckAsync,ClearAsync,DblClickAsync
        /// </summary>
        /// <param name="execute">操作类型，首字母大写</param>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> PageGoQSele(string execute, string elementPath)
        {
            IElementHandle element = await page.QuerySelectorAsync(elementPath);
            if (element != null)
            {
                await Execute(element, execute);
                return true;
            }
            else
            {
                await Print($"找不到元素 {elementPath}");
                return false;
            }
        }

        /// <summary> 
        /// 先判断元素是否存在，存在则执行 Click ，点击指定元素
        /// </summary>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> Click(string elementPath)
        {
            IElementHandle element =  await page.QuerySelectorAsync(elementPath);
            if (element != null)
            {
                await element.ClickAsync();
                return true;
            }
            else
            {
                await Print($"找不到元素 {elementPath}");
                return false;
            }
        }

        /// <summary>
        /// 先判断元素是否存在，存在则执行 Fill 将指定内容输入到文本输入框
        /// </summary>
        /// <param name="elementPath">元素定位表达式</param>
        /// <param name="text">输入的文本内容</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> Fill(string elementPath, string text)
        {
            IElementHandle element = await page.QuerySelectorAsync(elementPath);
            if (element != null)
            {
                await element.FillAsync(text);
                return true;
            }
            else
            {
                await Print($"找不到元素 {elementPath}");
                return false;
            }
        }

        /// <summary>
        /// 先判断元素是否存在，存在则执行 Clear 清空文本输入框
        /// </summary>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> Clear(string elementPath)
        {
            IElementHandle elementHandle = await page.QuerySelectorAsync(elementPath);
            if (elementHandle != null)
            {
                await page.Locator(elementPath).ClearAsync();
                return true;
            }
            else
            {
                await Print($"找不到元素 {elementPath}");
                return false;
            }
        }

        /// <summary>
        /// 打开指定网页
        /// </summary>
        /// <param name="url">网址</param>
        public async Task WaitUrl(string url)
        {
            await page.WaitForURLAsync(url);
        }

        /// <summary>
        /// 通过 Locator 检查元素是否存在
        /// </summary>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> CheckForLoca(string element) 
        {
            ILocator ele = page.Locator(element);
            if (await ele.CountAsync() > 0) return true;
            return false;
        }

        /// <summary>
        /// 通过 QuerySelectorAsync 检查元素是否存在
        /// </summary>
        /// <param name="elementPath">元素定位表达式</param>
        /// <returns>执行成功返回true</returns>
        public async Task<bool> CheckForQSele(string element)
        {
            IElementHandle ele = await page.QuerySelectorAsync(element);
            if (ele != null) return true;
            return false;
        }
    }
}
